package top.mingyi4cjh.cms.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.mingyi4cjh.cms.common.error.BusinessException;
import top.mingyi4cjh.cms.common.error.EmBusinessError;
import top.mingyi4cjh.cms.common.utils.CosUtil;
import top.mingyi4cjh.cms.common.utils.FilePathFactory;
import top.mingyi4cjh.cms.common.utils.FileUtil;
import top.mingyi4cjh.cms.dao.FileInfoDao;
import top.mingyi4cjh.cms.dataobject.FileInfoDO;
import top.mingyi4cjh.cms.model.FileModel;
import top.mingyi4cjh.cms.model.UserModel;
import top.mingyi4cjh.cms.service.FileService;

import javax.annotation.Resource;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static top.mingyi4cjh.cms.common.utils.Field.SEPARATOR;

/**
 * @author MingYi
 * @program cms
 * @create 2022/04/26 23:59
 */
@Service
public class FileServiceImpl implements FileService {

    @Resource
    private FileInfoDao fileInfoDao;

    @Resource
    private FilePathFactory filePathFactory;

    @Resource
    private FileUtil fileUtil;

    @Override
    public void uploadFile(Long fileId, MultipartFile multipartFile, Long userId) {
        //获取文件信息，包括文件名、文件类型、文件大小
        String fileName = multipartFile.getOriginalFilename();
        String fileType = multipartFile.getContentType();
        long fileSize = multipartFile.getSize();
        //拼接文件路径
        String filePath = "/" + userId + "/" + fileName;
        //生成现在时间
        Date now = new Date(System.currentTimeMillis());

        //保存文件到拼接出来的文件路径，对应的PATH+文件全名，包括扩展名
        //写入文件

        try {
            // 上传文件到COS
            File targetFile = FileUtil.MultipartFileToFile(multipartFile);
            CosUtil.uploadFile(targetFile, filePath);
            FileUtil.deleteFile(fileName);
            // 这里我怀疑有坑，或许入参应该统一一下。
        } catch (IOException e) {
            throw new BusinessException(EmBusinessError.FILE_PROCESS_ERROR);
        }

        //将上述信息存储进一个DO对象
        FileInfoDO fileInfoDO = new FileInfoDO();
        fileInfoDO.setFileId(fileId);
        fileInfoDO.setFileName(fileName);
        fileInfoDO.setFileType(fileType);
        fileInfoDO.setFileSize(fileSize);
        fileInfoDO.setFileUrl(filePath);
        fileInfoDO.setUploadTime(now);
        fileInfoDO.setUserId(userId);

        //写入数据库
        fileInfoDao.insert(fileInfoDO);
    }

    @Override
    public boolean isFileOwner(Long userId, Long fileId) {
        FileInfoDO result = fileInfoDao.selectByPrimaryKey(fileId);
        return result != null && userId.equals(result.getUserId());
    }

    @Override
    public String downFile(Long fileId) {
        FileInfoDO fileInfo = fileInfoDao.selectByPrimaryKey(fileId);
        String fileUrl = fileInfo.getFileUrl();
        return fileUrl;

//        String filename = fileInfo.getFileName();
//        ResponseEntity<InputStreamResource> body = null;
//        //从数据库中查对应的file信息，判断结果是不是空，空则抛出FAIL_NOT_EXIST
//        try {
//            FileInputStream fileInputStream = new FileInputStream(filename);
//            if (fileInputStream == null) {
//                throw new BusinessException(EmBusinessError.FILE_NOT_EXIST);
//            }
//            //去对应的url找到文件，再执行下载逻辑
//            byte[] bytes = new byte[fileInputStream.available()];
//            HttpHeaders headers = new HttpHeaders();
//            headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
//            headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", filename));
//            headers.add("Pragma", "no-cache");
//            headers.add("Expires", "0");
//            body = ResponseEntity
//                    .ok()
//                    .headers(headers)
//                    .contentLength(bytes.length)
//                    .contentType(MediaType.parseMediaType("application/octet-stream"))
//                    .body(new InputStreamResource(fileInputStream));
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return body;
    }

    @Override
    public void deleteFile(Long fileId) {
        FileInfoDO fileInfo = fileInfoDao.selectByPrimaryKey(fileId);
        String filename = fileInfo.getFileName();
        try {
            FileInputStream fileInputStream = new FileInputStream(filename);
            //从数据库中查对应的file信息，判断结果是不是空，空则直接return
            if (fileInputStream == null) {
                return;
            }
            //调用dao的delete方法
            //判断文件是否已经删除
            if (fileInfo.getDeleted()) {
                return;
            }
            //设置文件已经删除，但不在数据库中进行删除
            fileInfo.setDeleted(true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<FileModel> getFileList(Long userId) {
        List<FileModel> fileModels = new ArrayList<>();
        //从数据库中查询FileInfoDO列表
        List<FileInfoDO> fileInfoDO = fileInfoDao.selectByUserId(userId);
        //将FileInfoDO列表转换为FileModel列表并返回
        for (int i = 0; i < fileInfoDO.size(); i++) {
            FileModel fileModel = convertFromFileInfo(fileInfoDO.get(i));
            fileModels.add(fileModel);
        }

        return fileModels;
    }

    @Override
    public String previewFilePath(Long fileId) {
        FileInfoDO fileInfoDO = fileInfoDao.selectByPrimaryKey(fileId);
        String filePath = fileInfoDO.getFileUrl();

        if (StringUtils.isBlank(filePath)) {
            throw new BusinessException(EmBusinessError.FILE_NOT_EXIST);
        }
        filePath = filePath.replace("\\", SEPARATOR);
        filePath = filePath.replace("/", SEPARATOR);
//        String[] fileTypeArr = {"doc", "docx", "wps", "wpt", "xls", "xlsx", "et", "ppt", "pptx", "pdf","xlsm"};
        //判断是否可以转换或预览
//        int i = filePath.lastIndexOf(".");
//        String fileType = filePath.substring(i + 1);
        boolean flag = filePathFactory.isCanConvert(fileInfoDO.getFileType());
//        for (String type : fileTypeArr) {
//            if (type.equals(fileType)) {
//                flag = true;
//                break;
//            }
//        }

        return flag ? filePath : null;
    }

    @Override
    public FileModel convertFromFileInfo(FileInfoDO fileInfoDO) {
        if (fileInfoDO == null) {
            return null;
        }
        FileModel fileModel = new FileModel();
        BeanUtils.copyProperties(fileInfoDO, fileModel);
        return fileModel;
    }
}
